package pers.luchuan.consumer.hystrix;

import com.netflix.hystrix.*;
import org.springframework.web.client.RestTemplate;

/**
 * 配置线程池
 */
public class ConsumerCommand extends HystrixCommand<String> {
    private RestTemplate restTemplate;

    public ConsumerCommand(RestTemplate restTemplate) {
        super(setter());
        this.restTemplate = restTemplate;
    }

    private static Setter setter() {
        // 服务分组
        HystrixCommandGroupKey groupKey =
                HystrixCommandGroupKey.Factory.asKey("consumer_provider");
        // 服务标识
        HystrixCommandKey commandKey =
                HystrixCommandKey.Factory.asKey("provider");
        // 线程池名称
        HystrixThreadPoolKey threadPoolKey =
                HystrixThreadPoolKey.Factory.asKey("consumer_provider_pool");
        /**
         * 线程池配置
         * withCoreSize : 线程池大小为10
         * withKeepAliveTimeMinutes: 线程存活时间15秒
         * withQueueSizeRejectionThreshold :队列等待的阈值为100,超过100执行拒绝策略（fallback)
         */
        HystrixThreadPoolProperties.Setter threadPoolProperties =
                HystrixThreadPoolProperties.Setter().withCoreSize(5)
                        .withKeepAliveTimeMinutes(15).withQueueSizeRejectionThreshold(10);
        // 命令属性配置Hystrix 开启超时
        HystrixCommandProperties.Setter commandProperties =
                HystrixCommandProperties.Setter()
                        // 采用线程池方式实现服务隔离（3） 配置调用
                        .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
                        // 禁止
                        .withExecutionTimeoutEnabled(false);
        return HystrixCommand.Setter.withGroupKey(groupKey).andCommandKey(commandKey).andThreadPoolKey(threadPoolKey)
                        .andThreadPoolPropertiesDefaults(threadPoolProperties).andCommandPropertiesDefaults(commandProperties);
    }

    @Override
    protected String run() throws Exception {
        return restTemplate.getForObject("http://service-provider/provider/2", String.class);
    }

    @Override
    protected String getFallback() {
        return "熔断降级";
    }
}